home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 5046 < prev    next >
Encoding:
Text File  |  1996-08-06  |  5.6 KB  |  132 lines

  1. Newsgroups: comp.lang.c++
  2. Path: netcom.com!marnold
  3. From: marnold@netcom.com (Matt Arnold)
  4. Subject: Re: Aborting Constructors, Part II
  5. Message-ID: <marnoldDM529E.3CH@netcom.com>
  6. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  7. References: <4eoeck$t6n@news.ios.com> <4eq99t$fpu@fsuj01.rz.uni-jena.de>
  8. Date: Fri, 2 Feb 1996 08:00:26 GMT
  9. Sender: marnold@netcom7.netcom.com
  10.  
  11. mkt@isun04.inf.uni-jena.de (Tilo Koerbs) writes:
  12.  
  13. >> test::test(){
  14. >>     cout << "constructing object\n";
  15. >>     delete this;
  16. >>     throw(xmsg(string("deleted the object!\n")));
  17. >> }
  18.  
  19. >I am sure that using delete on this is not allowed in C++.
  20.  
  21. That is not correct.  It is allowed and, while some folks dislike it on
  22. a conceptual basis, it can be a quite useful capability for objects to
  23. destroy themselves.
  24.  
  25. However, you are correct if you mean to say that using "delete this" 
  26. in the above code is not *proper*.  It is certainly legal code, but it
  27. will likely not function correctly.  It's simply wrong and here are
  28. three good reasons why... 
  29.  
  30. Problem 1:  What if a "test" object was allocated on the stack or as a 
  31. static object, and then the constructor failed?  delete would be passed
  32. an address that obviously didn't come from the heap.  This would probably
  33. have the effect of corrupting the heap, or immediately crashing the
  34. program.
  35.  
  36. Problem 2:  The language already provides an automatic call to delete 
  37. iff you throw an exception from an object that was allocated using new.
  38. The code above would cause delete to be called twice!  Once again, heap
  39. corruption is likely.
  40.  
  41. Problem 3:  In the general case, calling "delete this" from the ctor is
  42. not correct (not only because of the above two problems), but because 
  43. "delete this" will cause the destructor (test::~test) to be called.  The
  44. destructor is likely to behave incorrectly since it only expects to get
  45. called for a successfully constructed object.  If you call "delete this"
  46. in the midst of a constructor, the destructor will attempt to destory an
  47. only *partially* valid object!  That's a recipe for trouble, for sure.
  48.  
  49. NOTE:  If you are thinking that Problem 2 doesn't look right because it
  50. says that the compiler calls delete for you, don't worry.  It does not 
  51. introduce the same issues as in Problem 3 because, when the compiler 
  52. automatically calls delete for you, it is *only* to free the memory.
  53. Conceptually, the compiler generates code something like this...
  54.  
  55.    delete((void*)this);
  56.  
  57. ...and no destructor is called.  Only memory is freed.
  58.  
  59. In short, the "delete this" is the above code is not only unnecessary, it's
  60. just plain wrong.
  61.  
  62. >I can remember that Borland is a little bit strange in those things.
  63.  
  64. Really?  So far, Boralnd has had one of the most robust and up-to-date C++ 
  65. implementations available for the PC, if anywhere.  If you mean to say that 
  66. Borland is strange for allowing "delete this", you are wrong.  Any C++ 
  67. compiler would be in error if it did not allow you to write "delete this".
  68.  
  69. >They allow a 'return 0' in constructors if the object cannot be constructed
  70. >and something else.
  71.  
  72. Constructors cannot return values.  Borland C++ does not allow constructors
  73. to return a value.
  74.  
  75. >While running a member function one cannot delete the object the function
  76. >is working on. After the delete the object the function works with is
  77. >not valid any more. So what is the function working with?
  78.  
  79. Yes, the programmer must be careful not to reference an object (internally
  80. or externally) after it has been deleted, but that is always the case, right?
  81. Obviously.  Yet, it is not illegal to use "delete this".  Even if "delete 
  82. this" were not allowed, you could still do...
  83.  
  84. void Object::KillMyself()
  85.    {
  86.    Object* pobj = this;
  87.  
  88.    delete pobj;
  89.    }
  90.  
  91. It's not "delete this", but does exactly the same thing.
  92.  
  93. Sure, "delete this" is dangerous if the programmer doesn't realize what is
  94. going on, and refers to an object after it has been destoryed.  However, if
  95. you find yourself using "delete this" without realizing what you are doing,
  96. your C++ skills need some more work, IMO.
  97.  
  98. If you don't like the "delete this" construct (as some poeple don't), then
  99. simply don't use it, and you'll never have to worry about the mistakes you
  100. might make with it.
  101.  
  102. >The output is absolutely correct (if the program not crashes, which is a valid
  103. >behaviour in such cases).
  104.  
  105. >But why can't you abort the constructor without this delete?
  106. >Before throwing the exception you can free all dynamically (inside the
  107. >constructor) created things.
  108.  
  109. I've lost track of what you are trying to say here (pehaps some text is
  110. missing from a previous posting), but your initial points regarding what
  111. is or is not legal in C++ are not correct.  
  112.  
  113. I think the original poster assumed that "delete this" was the proper thing
  114. to do when throwing an exception from a ctor.  But, because of at least the 
  115. three problems above, it is not.  The langauge already provides a way for a 
  116. partially constructed object to be partially deconstructed in such cases (as 
  117. well as for the memory used for the dynamically allocated object to be freed
  118. automatically).
  119.  
  120. There are many excellent C++ books that describe how exceptions work and
  121. can be used, even in the presence of dynamically allocated memory and from
  122. within constructors.
  123.  
  124. Regards,
  125. -------------------------------------------------------------------------
  126. Matt Arnold                       |        | ||| | |||| |  | | || ||
  127. marnold@netcom.com                |        | ||| | |||| |  | | || ||
  128. Boston, MA                        |      0 | ||| | |||| |  | | || ||
  129. 617.389.7384 (h) 617.576.2760 (w) |        | ||| | |||| |  | | || ||
  130. C++, MIDI, Win32/95 developer     |        | ||| 4 3 1   0 8 3 || ||
  131. -------------------------------------------------------------------------
  132.